#include <bits/stdc++.h>
#include "Interpolation.h"
using namespace std;

const static double pi = M_PI;
vector<double> x;
double xD[] = {0, 0, 3, 3, 5, 5, 8, 8, 13, 13};
double fD[] = {0, 75, 225, 77, 383, 80, 623, 74, 993, 72};
double xE[] = {0, 6, 10, 13, 17, 20, 28};
double fE1[] = {6.67, 17.3, 42.7, 37.3, 30.1, 29.3, 28.7};
double fE2[] = {6.67, 16.1, 18.9, 15.0, 10.6, 9.44, 8.89};

class fB : public Function{
public:
    double operator()(const double &x) const {return 1/(1+x*x);}
}fb;

class fC : public Function{
public:
    double operator()(const double &x) const {return 1/(1+25*x*x);}
}fc;

void setpoints( const int &n, const double &a, const double &e){
    for (int i = 0; i <= n; i++){
        x.push_back(a + e * i / n);
    }
}

void setcircle( const int &n, const double &e){
    for (int i = 1; i <= n; i++){
        x.push_back(cos((2 * i - 1) / (e * n) * pi));
    }
}


void testB(const int &n){
    setpoints( n, -5, 10);
    Hermite B(fb, x);
    B.poly();
    B.printpoly();
    x.clear();
}

void testC(const int &n){
    setcircle( n, 2.0);
    Hermite C(fc, x);
    C.poly();
    C.printpoly();
    x.clear();
}

void testD(const int &n){
    vector<double> xd(xD, xD + n);
    vector<double> fd(fD, fD + n); 
    Hermite D(xd,fd);
    D.poly();
    D.printpoly();
}

void testE1(const int &n){
    vector<double> xe(xE, xE + n);
    vector<double> fe1(fE1, fE1 + n); 
    Hermite E1(xe,fe1);;
    E1.poly();
    E1.printpoly();
}

void testE2(const int &n){
    vector<double> xe(xE, xE + n);
    vector<double> fe2(fE2, fE2 + n); 
    Hermite E2(xe,fe2);
    E2.poly();
    E2.printpoly();
}

int main()
{
    cout << "Probelm B" << endl;
    cout << "p(x)=";
    testB(2);
    cout << endl;
    cout << "p(x)=";
    testB(4);
    cout << endl;
    cout << "p(x)=";
    testB(6);
    cout << endl;
    cout << "p(x)=";
    testB(8);
    cout << endl;
    cout << "Probelm C" << endl;
    cout << "p(x)=";
    testC(5);
    cout << endl;
    cout << "p(x)=";
    testC(10);
    cout << endl;
    cout << "p(x)=";
    testC(15);
    cout << endl;
    cout << "p(x)=";
    testC(20);
    cout << endl;
    cout << "Probelm D" << endl;
    cout << "p(x)=";
    testD(10);
    cout << endl;
    cout << "Probelm E1" << endl;
    cout << "p(x)=";
    testE1(7);
    cout << endl;
    cout << "Probelm E2" << endl;
    cout << "p(x)=";
    testE2(7);


    return 0;
}